package com.myapi.ModelPoker;
import java.io.Serializable;
import java.util.*;

import com.myapi.client.PlayerHandDAO;
import com.myapi.client.DAO.CardDAO;
import com.myapi.client.DAO.PlayerDAO;



public class PlayerHand implements Comparable,Serializable {
	Player player;
	boolean mucked;
	boolean allIn;
	Set<Card> cards;
	double odds;
	ArrayList<Double> raise;
	ArrayList<Double> call;
	double chipsDiff;
		
	public PlayerHand(){
		
	}
	public PlayerHand(Player player) {
		this.player = player;
		setMucked(false);
		setAllIn(false);
		odds=0.0;
		cards = new TreeSet<Card>();
		raise=new ArrayList<Double>();
		call=new ArrayList<Double>();
		chipsDiff=0;
	}
	
	public void addCard(Card card) {
		cards.add(card);
	}
	
	public void removeCard(Card card) {
		cards.remove(card);
	}
	
	public Set<Card> getCards() {
		return cards;
	}
	
	public Player getPlayer() {
		return player;
	}
	
	public void setMucked(boolean muck) {
		if(muck) {
                    cards.clear();
                    mucked = true;
		} else {
                    mucked = false;
		}
	}
	
	public boolean getMucked() {
		return mucked;
	}
	
	public int getNumCards() {
		return cards.size();
	}
	
	public RankedHand getRankedHand() {
		//CardAnalyser regAna = CardAnalyser.getCardAnalyser(CardAnalyser.REGULAR);
                CardAnalyser regAna = new RegularCardAnalyser();
		RankedHand hand = regAna.analyseCards(getCards());
		return hand;
	}
	
	/**
	 * Compare with the rank Hand
	 */
	public int compareTo(Object o) {
		assert o instanceof PlayerHand;
		PlayerHand hand = (PlayerHand) o;
		RankedHand rHand = hand.getRankedHand();
		return rHand.compareTo(getRankedHand());
	}
	
	//PlayerHands are equal if they have the same Player
	public boolean equals(Object o) {
		if(o instanceof PlayerHand) {
			PlayerHand playerHand = (PlayerHand) o;
			Player pl = playerHand.getPlayer();
			return pl.equals(getPlayer());
		}
		else {
			return false;
		}
	}
	
	public int hashCode() {
		return getPlayer().hashCode();
	}

	public boolean isAllIn() {
		return allIn;
	}
	public void setAllIn(boolean allIn) {
		this.allIn = allIn;
	}
	public double getOdds() {
		return odds;
	}
	public void setOdds(double odds) {
		this.odds = odds;
	}

	public double getChipsDiff() {
		return chipsDiff;
	}
	private void setChipsDiff(double chipsDiff) {
		this.chipsDiff = chipsDiff;
	}
	public void addCall(double amount){
		this.call.add(amount);
		setChipsDiff(getChipsDiff()-amount);
	}
	public void addRaise(double amount){
		this.raise.add(amount);
		setChipsDiff(getChipsDiff()-amount);
	}
	public void addChips(double amount) {
		chipsDiff=chipsDiff+amount;
		
	}
	public void removeChips(double amount) {
		chipsDiff=chipsDiff-amount;
		
	}
	public PlayerHandDAO getInfo() {
		PlayerHandDAO playerHandDAO=new PlayerHandDAO();
		playerHandDAO.setMucked(this.getMucked());
		playerHandDAO.setPlayerInfo(this.getPlayer().getInfo());
		playerHandDAO.setAllIn(this.allIn);
		playerHandDAO.setCall(this.call);
		playerHandDAO.setChipsDiff(getChipsDiff());
		playerHandDAO.setOdds(getOdds());
		playerHandDAO.setRaise(this.raise);
		
		ArrayList<CardDAO> cardsInfo=new ArrayList<CardDAO>();
		Iterator<Card> iterator=this.cards.iterator();

		while(iterator.hasNext()){
			cardsInfo.add(iterator.next().getInfo());
		}
		
		playerHandDAO.setCards(cardsInfo);
		return playerHandDAO;
	}
	public PlayerHandDAO getInfo(PlayerDAO playerDAO) {
		PlayerHandDAO playerHandDAO=new PlayerHandDAO();
		playerHandDAO.setMucked(this.getMucked());
		playerHandDAO.setPlayerInfo(playerDAO);
		playerHandDAO.setAllIn(this.allIn);
		playerHandDAO.setCall(this.call);
		playerHandDAO.setChipsDiff(getChipsDiff());
		playerHandDAO.setOdds(getOdds());
		playerHandDAO.setRaise(this.raise);
		
		ArrayList<CardDAO> cardsInfo=new ArrayList<CardDAO>();
		Iterator<Card> iterator=this.cards.iterator();

		while(iterator.hasNext()){
		CardDAO card=iterator.next().getInfo();
			cardsInfo.add(card);
			playerHandDAO.addCardKey(card);
		}
		
		playerHandDAO.setCards(cardsInfo);
		return playerHandDAO;
	}
}
